package suncertify.application;

import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

/**
 * A class that provides application log functionality. The class contains only static methods. The constructor of the
 * class is private and the class itself is final. The class is a wrapper for the java {@link Logger} class.
 * 
 * <p>
 * The <code>Log</code> class is initialized once when the application is started in the {@link Application#main}
 * method. The class uses the {@link SimpleFormatter} to format its log information. The log data is saved in a log file
 * that is defined by the {@link #LOG_FILE_NAME} constant. The log file is saved in the user's current working
 * directory.
 * 
 * <p>
 * The <code>logFine</code>,<code>logInfor</code> and <code>logSevere</code> methods should only be called after the
 * <code>initializeLogger</code> was called successfully.
 * 
 * <p>
 * The class provides three log levels, <code>Fine</code>, <code>Info</code> and <code>Severe</code>.
 * 
 * @see Logger
 */
public final class Log {

    /**
     * Name of the internal {@link Logger} instance.
     */
    private final static String LOGGER_NAME = "suncertifyLogger";

    /**
     * Name of the log file.
     */
    private final static String LOG_FILE_NAME = "suncertify.log";

    /**
     * Instance of the {@link Logger} instance. All log methods of this function use the <code>logger</code> instance.
     */
    private static Logger logger = null;

    /**
     * Private constructor. Prevents unnecessary instantiation of this class that has not state and contains only static
     * methods.
     */
    private Log() {

    }

    /**
     * Initializes the internal {@link Logger} object. The internal <code>Logger</code> object uses a
     * {@link FileHandler} and a {@link SimpleFormatter}. The log level of the internal <code>Logger</code> is set to
     * {@link Level#ALL}
     * 
     * @throws SecurityException
     *             see {@link FileHandler} and {@link FileHandler#setFormatter(java.util.logging.Formatter)}
     * @throws IOException
     *             see {@link FileHandler}
     */
    public static void initializeLogger() throws SecurityException, IOException {

	// attach a file handler to the logger.
	FileHandler fileHandler = new FileHandler(LOG_FILE_NAME);

	// format the log data in a simply way.
	fileHandler.setFormatter(new SimpleFormatter());

	// Create the application logger object.
	logger = Logger.getLogger(LOGGER_NAME);

	// attach the file handler to the logger. All log messages will be directed to the file handler.
	logger.addHandler(fileHandler);

	// enable all log levels.
	logger.setLevel(Level.ALL);
    }

    /**
     * Logs the <code>message</code> in the application's log file with level <code>Severe</code>. Use this method to
     * log serious errors that prevent the application from running.
     * 
     * @param message
     *            The message to be logged.
     */
    public static void logSevere(String message) {

	if (message == null)
	    return;

	if (logger == null)
	    return;

	logger.severe(message);
    }

    /**
     * Logs the <code>message</code> in the application's log file with level <code>Info</code>. Use this method to log
     * information you think are valuable to analyze the program usage, e.g. you can log all search and book requests.
     * 
     * @param message
     *            The message to be logged.
     */
    public static void logInfo(String message) {

	if (message == null)
	    return;

	if (logger == null)
	    return;

	logger.info(message);
    }

    /**
     * Logs the <code>message</code> in the application's log file with level <code>Fine</code>. Use this log level if
     * you want to log fine operations e.g. you many want to log each database file read and write operation.
     * 
     * @param message
     *            The message to be logged.
     */
    public static void logFine(String message) {

	if (message == null)
	    return;

	if (logger == null)
	    return;

	logger.fine(message);
    }
}
